package com.hanhai.material.wxauth.controller;

import com.hanhai.material.common.result.Result;
import com.hanhai.material.common.result.ResultTool;
import com.hanhai.material.wxauth.entity.SysMenu;
import com.hanhai.material.wxauth.entity.SysRoleMenu;
import com.hanhai.material.wxauth.service.SysMenuService;
import com.hanhai.material.wxauth.service.SysRoleMenuService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

import static com.hanhai.material.wxauth.entity.table.SysMenuTableDef.SYS_MENU;
import static com.hanhai.material.wxauth.entity.table.SysRoleMenuTableDef.SYS_ROLE_MENU;
import static com.mybatisflex.core.query.QueryMethods.distinct;
import static com.mybatisflex.core.query.QueryMethods.pi;

/**
 * 控制层。
 *
 * @author youchuang
 * @since 2023/10/18 14:41:16
 */
@RestController
@RequestMapping("/menu")
@Log4j2
public class SysMenuController {

    @Autowired
    private SysMenuService sysMenuService;
    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @PostMapping("/list/{type}")
    private Result<?> list(@PathVariable String type) {
        log.error("Type：{}", type);
//        queryWrapper.where(SYS_MENU.PARENT_ID.eq("self"));
        if (!type.equals("index")) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.where(SYS_MENU.MENU_TYPE.eq(type));
            queryWrapper.where(SYS_MENU.IS_DELETE.eq(0));
            queryWrapper.where(SYS_MENU.PARENT_ID.ne("self"));
            queryWrapper.orderBy(SYS_MENU.MENU_ORDER, true);
            List<SysMenu> menuList = this.sysMenuService.getMapper().selectListWithRelationsByQuery(queryWrapper);
            return menuList.isEmpty() ? ResultTool.fail() : ResultTool.success(menuList);
        } else {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.select(distinct(SYS_MENU.MENU_TYPE_NAME, SYS_MENU.MENU_TYPE));
            queryWrapper.where(SYS_MENU.IS_DELETE.eq(0));
            queryWrapper.where(SYS_MENU.PID.ne("parent"));
            queryWrapper.where(SYS_MENU.MENU_TYPE.eq(type));
            queryWrapper.orderBy(SYS_MENU.MENU_ORDER, true);
            List<SysMenu> sysMenus = this.sysMenuService.list(queryWrapper);
            for (SysMenu sysMenu : sysMenus) {
                QueryWrapper queryWrapper1 = new QueryWrapper();
                queryWrapper1.where(SYS_MENU.MENU_TYPE.eq(type));
                queryWrapper1.where(SYS_MENU.IS_DELETE.eq(0));
                queryWrapper1.orderBy(SYS_MENU.MENU_ORDER, true);
                queryWrapper1.where(SYS_MENU.MENU_TYPE_NAME.eq(sysMenu.getMenuTypeName()));
                List<SysMenu> menuList = this.sysMenuService.getMapper().selectListWithRelationsByQuery(queryWrapper1);
                sysMenu.setMenuList(menuList);
            }
            return sysMenus.isEmpty() ? ResultTool.fail() : ResultTool.success(sysMenus);
        }
    }

    @PostMapping("/list1/{pid}")
    private Result<?> list1(@PathVariable String pid) {
        log.error("Type：{}", pid);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.where(SYS_MENU.PID.eq(pid));
        queryWrapper.where(SYS_MENU.IS_DELETE.eq(0));
        queryWrapper.orderBy(SYS_MENU.MENU_ORDER,true);
        List<SysMenu> menuList=this.sysMenuService.list(queryWrapper);
        return menuList.isEmpty() ? ResultTool.fail() : ResultTool.success(menuList);
    }

    @GetMapping("/admin/list/parent")
    private Result<?> getList() {
        QueryWrapper queryWrapper = QueryWrapper.create();
        queryWrapper.where(SYS_MENU.PID.eq("parent"));
        queryWrapper.orderBy(SYS_MENU.MENU_ORDER, true);
        List<SysMenu> sysMenuList = this.sysMenuService.getMapper().selectListWithRelationsByQuery(queryWrapper);
//        for(SysMenu sysMenu:sysMenuList){
//            for(SysMenu menu:sysMenu.getMenuList()){
//                queryWrapper=QueryWrapper.create();
//                queryWrapper.where(SYS_MENU.PID.eq(menu.getId()));
//                queryWrapper.orderBy(SYS_MENU.MENU_ORDER,true);
//                List<SysMenu> sysMenuList1=this.sysMenuService.getMapper().selectListWithRelationsByQuery(queryWrapper);
//                menu.setMenuList(sysMenuList1);
//            }
//
//        }
        return sysMenuList.isEmpty() ? ResultTool.fail() : ResultTool.success(sysMenuList);
    }

    @GetMapping("/admin/listByPage/{page}/{size}")
    public Result<?> getMenuListByPage(@PathVariable long page, @PathVariable long size) {
        Page<SysMenu> p = new Page<>(page, size);
        QueryWrapper queryWrapper = QueryWrapper.create();
        queryWrapper.where(SYS_MENU.PID.eq("parent"));
        queryWrapper.orderBy(SYS_MENU.MENU_ORDER, true);
//        List<SysMenu> sysMenuList=this.sysMenuService.getMapper().selectListWithRelationsByQuery(queryWrapper);
        Page<SysMenu> menuPage = this.sysMenuService.getMapper().paginateWithRelations(p, queryWrapper);
        if (menuPage.getRecords().isEmpty()) {
            return ResultTool.fail();
        } else {
            for (SysMenu sysMenu : menuPage.getRecords()) {
                Comparator<SysMenu> menuComparator = Comparator.comparing(SysMenu::getMenuOrder).thenComparing(SysMenu::getMenuName);
                Collections.sort(sysMenu.getMenuList(), menuComparator);
            }
            return ResultTool.success(menuPage);
        }

    }

    @PostMapping("/list/{type}/{workShop}")
    private Result<?> list(@PathVariable String type, @PathVariable String workShop) {
        QueryWrapper queryWrapper = new QueryWrapper();
//        queryWrapper.where(SYS_MENU.PARENT_ID.eq("self"));
//        queryWrapper.select(distinct(SYS_MENU.W))
        queryWrapper.where(SYS_MENU.MENU_TYPE.eq(type));
        queryWrapper.where(SYS_MENU.IS_DELETE.eq(0));
        queryWrapper.orderBy(SYS_MENU.MENU_ORDER, true);
        List<SysMenu> menuList = this.sysMenuService.getMapper().selectListWithRelationsByQuery(queryWrapper);
        return menuList.isEmpty() ? ResultTool.fail() : ResultTool.success(menuList);
    }

    @PostMapping("/admin/add")
    public Result<?> addMenu(@RequestBody SysMenu sysMenu) {
        sysMenu.setCreateTime(new Date());
        sysMenu.setId(UUID.randomUUID().toString());
        if (sysMenu.getPid().equals("parent")) {
            sysMenu.setParentId("self");
        }
        boolean result = this.sysMenuService.save(sysMenu);
        return result ? ResultTool.success() : ResultTool.fail();
    }

    @PostMapping("/admin/update")
    public Result<?> updateMenu(@RequestBody SysMenu sysMenu) {

        sysMenu.setUpdateTime(new Date());
        boolean result = this.sysMenuService.updateById(sysMenu);
        return result ? ResultTool.success() : ResultTool.fail();
    }

    @GetMapping("/admin/list/role/{roleId}/{level}")
    public Result<?> getRoleMenuList(@PathVariable String roleId, @PathVariable Integer level) {
        System.out.println("RoleLevel:" + level);
        List<SysMenu> sysMenuList = new ArrayList<>();
        if (level == 1) {
            QueryWrapper queryWrapper = QueryWrapper.create();
            queryWrapper.where(SYS_MENU.PID.eq("parent")).orderBy(SYS_MENU.MENU_ORDER, true).where(SYS_MENU.IS_DELETE.eq(false));
            sysMenuList = this.sysMenuService.list(queryWrapper);
            for (SysMenu sysMenu : sysMenuList) {
                queryWrapper = QueryWrapper.create();
                queryWrapper.where(SYS_MENU.PID.eq(sysMenu.getId())).orderBy(SYS_MENU.MENU_ORDER, true).where(SYS_MENU.IS_DELETE.eq(false));
                List<SysMenu> menuList = this.sysMenuService.list(queryWrapper);
                sysMenu.setMenuList(menuList);
            }
        } else {
            QueryWrapper queryWrapper = QueryWrapper.create();
            queryWrapper.where(SYS_ROLE_MENU.ROLE_ID.eq(roleId));
            List<SysRoleMenu> sysRoleMenuList = this.sysRoleMenuService.list(queryWrapper);
            List<SysMenu> parentMenuList = new ArrayList<>();
            List<SysMenu> childMenuList = new ArrayList<>();
            for (SysRoleMenu sysRoleMenu : sysRoleMenuList) {
                SysMenu sysMenu = this.sysMenuService.getById(sysRoleMenu.getMenuId());
                if (sysMenu != null) {
                    if (sysMenu.getParentId().equals("parent")) {
                        parentMenuList.add(sysMenu);
                    } else {
                        childMenuList.add(sysMenu);
                    }
                }
            }
            System.out.println("Parent:" + parentMenuList);
            System.out.println("Children:" + childMenuList);
            for (SysMenu parent : parentMenuList) {
                List<SysMenu> childrenList = new ArrayList<>();
                for (SysMenu child : childMenuList) {
                    if (child.getPid().equals(parent.getId())) {
                        childrenList.add(child);
                    }
                }
                parent.setMenuList(childrenList);
            }
            sysMenuList = parentMenuList;
        }


        return sysMenuList.isEmpty() ? ResultTool.fail() : ResultTool.success(sysMenuList);
    }

    @GetMapping("/admin/list/{pageNumber}/{limit}")
    public Result<?> getSysMenuList(@PathVariable Long pageNumber, @PathVariable Long limit) {
        Page<SysMenu> pageObject = new Page<>(pageNumber, limit);
        QueryWrapper queryWrapper = QueryWrapper.create();
        queryWrapper.where(SYS_MENU.PID.eq("parent"));
        queryWrapper.orderBy(SYS_MENU.MENU_ORDER, true);
        Page<SysMenu> sysMenuPage = this.sysMenuService.getMapper().paginateWithRelations(pageObject, queryWrapper);
        for (SysMenu sysMenu : sysMenuPage.getRecords()) {
//            queryWrapper=new QueryWrapper<>();
//            sysMenuQueryWrapper.eq("PId",sysMenu.getId());
//            sysMenuQueryWrapper.orderByAsc("order_no");
//            List<SysMenu> sysMenuList=this.sysMenuService.list(sysMenuQueryWrapper);
//            sysMenu.setMenuList(sysMenuList);
//            SysUser createdUser=this.sysUserService.getById(sysMenu.getCreateUserId());
//            SysUser updateUser=this.sysUserService.getById(sysMenu.getUpdateUserId());
//            if(createdUser!=null){
//                sysMenu.setCreateUser(createdUser);
//            }
//            if(updateUser!=null){
//                sysMenu.setUpdateUser(updateUser);
//            }
        }
        return sysMenuPage.getRecords().isEmpty() ? ResultTool.fail() : ResultTool.success(sysMenuPage);
    }

    @PostMapping("/admin/delete/{uid}/{isDelete}")
    public Result<?> deleteSysMenu(@PathVariable String uid, @PathVariable Integer isDelete, @RequestBody SysMenu sysMenu) {
        boolean result = false;
        log.error("ISDelete:{}", isDelete);
        if (sysMenu.getPid().equals("parent")) {
            log.error("父菜单");
            QueryWrapper queryWrapper = QueryWrapper.create();
            queryWrapper.where(SYS_MENU.PID.eq(sysMenu.getId()));
            List<SysMenu> menuList = this.sysMenuService.list(queryWrapper);
            menuList.add(sysMenu);
            switch (isDelete) {
                case 0:
                    for (SysMenu menu : menuList) {
                        menu.setIsDelete(false);
                        menu.setUpdateTime(new Date());
                        menu.setUpdateUserId(uid);
                    }
                    result = this.sysMenuService.updateBatch(menuList);
                    break;
                case 1:
                    queryWrapper = QueryWrapper.create();
                    queryWrapper.where(SYS_MENU.ID.eq(sysMenu.getId()).or(SYS_MENU.PID.eq(sysMenu.getId())));
                    result = this.sysMenuService.remove(queryWrapper);

            }

        } else {
            log.error("非父菜单");
            switch (isDelete) {
                case 0:
                    sysMenu.setIsDelete(false);
                    sysMenu.setUpdateTime(new Date());
                    sysMenu.setUpdateUserId(uid);
                    result = this.sysMenuService.updateById(sysMenu);
                    break;
                case 1:
                    result = this.sysMenuService.removeById(sysMenu.getId());

            }

        }
        return result ? ResultTool.success() : ResultTool.fail();
    }
}
